// 
//  MyClass.cs
//  
//  Author:
//       BOUTRY Arnaud <lordphoenix@tuxfamily.org>
// 
//  Copyright (c) 2010 BOUTRY Arnaud as LordPhoenix <lordphoenix@tuxfamily.org>
// 
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//  
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// 

using System;
using System.IO;
using System.Collections;
using System.Net;
using System.Xml;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Gtk;
using swmt.swmtProvider;

[assembly:PluginInfo("Google Reader","Greader.gReader")]

namespace swmt.swmtProvider.Greader
{
	
	internal class GoogleCertificatePolicy : ICertificatePolicy
	{
		public GoogleCertificatePolicy ()
		{
		}
		public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
		{
			return true;
		}
	}

	public class gReader : WebService
	{
		private string _username;
		private string _password;
		private string _configfile;
		private int _lastcount;
		private string _sid;
		private string _token;
		private Cookie _cookie;

		public gReader ()
		{
			ServicePointManager.CertificatePolicy = new GoogleCertificatePolicy ();
			_lastcount = 0;
			Mono.Unix.Catalog.Init("swmt-plugins","");
		}
		public override void saveconfig (string filename)
		{
			_configfile = filename;
			FileStream fichier = File.Open (filename, FileMode.OpenOrCreate);
			StreamWriter w = new StreamWriter (fichier);
			w.BaseStream.Seek (0, SeekOrigin.Begin);
			string tmpstring = String.Format("username={0}",_username);
			w.WriteLine(tmpstring);
			tmpstring = String.Format("password={0}",_password);
			w.WriteLine (tmpstring);
			w.Flush ();
			fichier.Flush ();
			fichier.Close ();
			w.Close ();
		}
		public override void loadconfig (string filename)
		{
			_configfile = filename;
			FileStream fichier = File.Open (filename, FileMode.Open);
			StreamReader read = new StreamReader (fichier);
			read.BaseStream.Seek (0, SeekOrigin.Begin);
			string optionstring;
			while (!read.EndOfStream) {
				optionstring = read.ReadLine ();
				if (!optionstring.StartsWith ("#")) {
					if(optionstring.StartsWith("username")){
						int cpos = optionstring.IndexOf ("=");
						this._username = optionstring.Substring (cpos + 1, optionstring.Length - cpos - 1);
					}
					if(optionstring.StartsWith("password")){
						int cpos = optionstring.IndexOf("=");
						_password = optionstring.Substring(cpos+1,optionstring.Length-cpos-1);
					}
				}
			}
			read.Close ();
			fichier.Close ();
		}
		public override void deleteconfigfile(){
			File.Delete(_configfile);
		}
		public override string pluginfile {
			get {
				Assembly plug = Assembly.GetExecutingAssembly ();
				return plug.GetName ().Name+".dll";
			}
		}
		public override string servicename{
			get{return "Google Reader";}
		}
		public override int LastCount{
			get{return _lastcount;}
		}
		public override string Homepage{
			get{return "http://www.google.com/reader/view/";}
		}
		private void GetSID ()
		{
			try
			{
				string url = String.Format ("https://www.google.com/accounts/ClientLogin?service=reader&Email={0}&Passwd={1}"
					, _username, _password);
				HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create (url);
				wreq.Method = "GET";
				HttpWebResponse response = (HttpWebResponse)wreq.GetResponse ();
				Stream data = response.GetResponseStream ();
				StreamReader r = new StreamReader (data);
				string result = r.ReadToEnd ();
				_sid = result.Substring (result.IndexOf ("SID=") + 4, result.IndexOf ("LSID=") - 5);
				r.Close ();
			}
			catch (WebException we) {
				if (we.Status == WebExceptionStatus.TrustFailure)
					Console.WriteLine (we.Message);
				throw;
				}

		}
		private void GetToken ()
		{
			_cookie = new Cookie ("SID", _sid, "/", ".google.com");
			string url = "https://www.google.com/reader/api/0/token";
			HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create (url);
			AddCookie(wreq);
			HttpWebResponse wresp = (HttpWebResponse)wreq.GetResponse ();
			Stream data = wresp.GetResponseStream ();
			StreamReader r = new StreamReader (data);
			_token = r.ReadToEnd ();
			r.Close ();
		}
		public override bool connect ()
		{
			GetSID ();
			GetToken ();
			return _token != null;
		}
		private string GetUnreadFeeds (){
			/* return XML String wich contains id and count of unread items of each 
			 * feed wich get unread items */			
			string url = "https://www.google.com/reader/api/0/unread-count?all=true";
			HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create (url);
			AddCookie (wreq);
			wreq.Method = "GET";
			HttpWebResponse wresp = (HttpWebResponse)wreq.GetResponse ();
			StreamReader r = new StreamReader (wresp.GetResponseStream ());
			return r.ReadToEnd ();
		}
		
		private void AddCookie (HttpWebRequest wreq)
		{
			wreq.CookieContainer = new CookieContainer();
			wreq.CookieContainer.Add(_cookie);
		}
		public override int GetUnreadCount ()
		{
			int unreadcount = 0;
			XmlDocument xdoc = new XmlDocument ();
			xdoc.LoadXml (GetUnreadFeeds ());
			XmlNode ListNode = xdoc.DocumentElement.ChildNodes[1];
			XmlNodeList objectList = (ListNode as XmlElement).GetElementsByTagName ("object");
			foreach (XmlNode objectnode in objectList) {
				XmlNode idnode = objectnode.ChildNodes[0];
				string id = idnode.ChildNodes[0].Value;
				if (id.StartsWith ("feed")) {
					XmlNodeList numberlist = (objectnode as XmlElement).GetElementsByTagName ("number");
					unreadcount += Int32.Parse (numberlist[0].ChildNodes[0].Value);
				}

			}
			_lastcount = unreadcount;
			return unreadcount;
		}
		public override ResponseType Prompt (bool edit)
		{
			GreaderDialog dlg = new GreaderDialog();
			if(edit){
				dlg.username = _username;
				dlg.password = _password;
			}
			ResponseType result = (ResponseType)dlg.Run();
			if(result == ResponseType.Ok){
				_username = dlg.username;
				_password = dlg.password;
			}
			dlg.Hide();
			return result;
		}


	}
}
